package edu.ncsu.csc.ip.routing.dv.udp.serialize;

import edu.ncsu.csc.ip.routing.dv.Node;
import edu.ncsu.csc.ip.routing.dv.RouteEntity;

/**
 * Class <code>NodeSerializer</code>
 * 
 * Serializes node to string and visa versa
 * Note that only name and distance vector are serialized.
 * 
 * Examples "1=2,5.5,3|3,4.5,5|5,4.0,2" Means path from 1 to 2 has weight of 5.5
 * and next node on the path is 3
 * 
 * @author Moin Ayazifar <mayazif@ncsu.edu>
 * @author Steven Elliott <sdelliot@ncsu.edu>
 * 
 */

public class NodeSerializer {

	public static final String NODE_DELIM = "=";
	public static final String ROUTE_ENTITY_DELIM = "/";
	public static final String NODE_WEIGHT_DELIM = ",";

	public static Node bytesToNode(byte[] bytes) {
		return stringToNode(new String(bytes));
	}

	public static byte[] nodeToBytes(Node sourceNode) {
		return nodeToString(sourceNode).getBytes();
	}

	public static String nodeToString(Node sourceNode) {
		StringBuilder sb = new StringBuilder();
		sb.append(sourceNode.getName());
		sb.append(NODE_DELIM);
		RouteEntity re;
		for (Node destNode : sourceNode.distanceVector.keySet()) {
			sb.append(destNode.getName());
			sb.append(NODE_WEIGHT_DELIM);
			re = sourceNode.distanceVector.get(destNode);
			sb.append(re.weight);
			sb.append(NODE_WEIGHT_DELIM);
			sb.append(re.nextNode);
			sb.append(ROUTE_ENTITY_DELIM);
		}
		return sb.toString();
	}

	public static Node stringToNode(String s) {
		String[] node_dv = s.trim().split(NODE_DELIM);
		Node sourceNode = new Node(node_dv[0]);

		String[] reArray;
		// reArray[0] : Destination Node
		// reArray[1] : Total Weight from Source Node to Destination Node
		// reArray[2] : Thru Node
		for (String reString : node_dv[1].trim().split(ROUTE_ENTITY_DELIM)) {

			if (reString != null) {
				reArray = reString.split(NODE_WEIGHT_DELIM);
				if (reArray.length == 3)
					sourceNode.distanceVector.put(
							new Node(reArray[0]),
							new RouteEntity(new Node(reArray[2]), Double
									.parseDouble(reArray[1])));
			}
		}
		return sourceNode;
	}

	public static void main(String[] args) {
		// String s = "1=2,5.5,3/3,4.5,5/5,4.0,2//";
		String s = "192.168.0.1:5443=192.168.0.2:5443,5.5,192.168.0.3:5443/192.168.0.3:5443,4.5,192.168.0.5:5443/192.168.0.5:5443,4.0,192.168.0.2:5443/";

		Node n = bytesToNode(s.getBytes());
		byte[] b = nodeToBytes(n);
		System.out.println(b.length);
		n = bytesToNode(b);

		System.out.println(nodeToString(n));

		System.out.println(s);
	}
}
